package com.groovy.base.closure

import org.junit.Test

class GroovyClosureTest {

    static void main(String[] args) {
       GroovyClosureTest test  = new GroovyClosureTest()
        test.demoClosure()
        test.param()
        test.itDemo()

    }

    /**
     * 闭包是一个短的匿名代码块。它通常跨越几行代码。一个方法甚至可以将代码块作为参数
     */
    void demoClosure() {
        def clos = {println "Hello World"};
        clos.call();
    }

    /**
     * 闭包中的形式参数
     * 在下面的代码示例中，注意使用$ {param}，这导致closure接受一个参数。当通过clos.call语句调用闭包时，我们现在可以选择将一个参数传递给闭包。
     */
    void param() {
        def clos = {param->println "Hello ${param}"};
        clos.call("World111");
    }

    /**
     * 下一个重复了前面的例子并产生相同的结果，但显示可以使用被称为它的隐式单个参数。这里的'it'是Groovy中的关键字
     */
    void itDemo() {
        def clos = {println "Hello ${it}"};
        clos.call("World222");
    }


    @Test
    void closureAndParam() {
        def str1 = "Hello";
        def clos = {param -> println "${str1} ${param}"}
        clos.call("World");

        // We are now changing the value of the String str1 which is referenced in the closure
        str1 = "Welcome";
        clos.call("World");
    }


    /**
     * 闭包也可以用作方法的参数
     * @param clo  闭包作为入参
     * @return
     */

    def static Display(clo) {
        // This time the $param parameter gets replaced by the string "Inner"
        clo.call("Inner");
    }

    /**
     * 在方法中使用闭包
     */
    @Test
    void DisplayTest() {
        def str1 = "Hello";
        // 定义了一个闭包 clos
        def clos = { param -> println "${str1} ${param}" }
        clos.call("World");

        // We are now changing the value of the String str1 which is referenced in the closure
        str1 = "Welcome";
        clos.call("World");

        // Passing our closure to a method
        GroovyClosureTest.Display(clos);
    }


    /**
     * 数组中的闭包
     */
    @Test
    void closureOfArray() {
        def lst = [11, 12, 13, 14];
        lst.each {println it}
    }


    /**
     * ，我们首先定义一个简单的关键值项Map。然后，映射集合类型定义一个名为.each的函数。此函数将闭包作为参数，并将闭包应用于映射的每个键值对
     */
    @Test
    void closureOfMap() {
        def mp = ["TopicName" : "Maps", "TopicDescription" : "Methods in Maps"]
        mp.each {}
        mp.each {println it}
        println("================")
        mp.each {println "${it.key} maps to: ${it.value}"}
    }

    @Test
    void closureOfIf() {
        def lst = [1,2,3,4];
        lst.each {println it}
        println("The list will only display those numbers which are divisible by 2")
        lst.each{num -> if(num % 2 == 0) println num}
    }

}
